﻿using System.Reflection;
using System.IO;
using System.Web;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;

namespace Marbles.Core.Web.MVC.Controllers
{
    public class Controller : IHttpHandlerFactory
    {

        public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
        {

            if (url.ToLower() == "/favicon.ico") { return null; }
            RequestInfo target = new RequestInfo(context, requestType, url, pathTranslated);


            if (File.Exists(pathTranslated))
            {
                return GetExistingPageHandler(context, pathTranslated,target);
            }
            else
            {
                if (target.HasEnclosure())
                {
                    return GetEnclosureHandler(context, target);
                }
                else
                {
                    return GetPageHandler(context, target);
                }
            }

        }

        public IHttpHandler GetEnclosureHandler(HttpContext context, RequestInfo target)
        {
            Models.Model model = CreateTypeInstance(target.Enclosure.Model) as Models.Model;
            Views.View view = CreateTypeInstance(target.Enclosure.View) as Views.View;

            if (model == null) { throw new HttpException(404, "Unable to find Model."); }

            string filename = context.Server.MapPath(target.Enclosure.View);
            if (File.Exists(filename))
            {
                context.RewritePath(target.VirtualPath, target.VirtualPath, target.QueryString);
                context.Items["RawUrl"] = context.Request.RawUrl;
                Views.View appHandler = PageParser.GetCompiledPageInstance(target.VirtualPath, filename, context) as Views.View;
                model.InitialiseView(appHandler);
                appHandler.InitialiseModel(model);
                context.RewritePath(context.Items["RawUrl"].ToString());
                return appHandler;
            }

            throw new HttpException(404, "View not found.");
        }

        public static object CreateTypeInstance(string name)
        {
            Assembly assm = null;
            string[] arr = name.Split(',');
            if (arr.Length == 2)
            {
                assm = Assembly.Load(arr[1].Trim());
                object obj = assm.CreateInstance(arr[0].Trim());
                return obj;
            }

            return null;
        }

        public IHttpHandler GetPageHandler(HttpContext context, RequestInfo target)
        {
            string filename = context.Server.MapPath(target.VirtualPath);
            if (File.Exists(filename))
            {
                context.RewritePath(target.VirtualPath, target.VirtualPath, target.QueryString);
                context.Items["RawUrl"] = context.Request.RawUrl;
                IHttpHandler appHandler = PageParser.GetCompiledPageInstance(target.VirtualPath, filename, context);

                context.RewritePath(context.Items["RawUrl"].ToString());
                return appHandler;
            }

            throw new HttpException(404, "File not found");
        }

        public IHttpHandler GetExistingPageHandler(HttpContext context, string filename, RequestInfo target)
        {
            if (File.Exists(filename))
            {
                context.RewritePath(target.VirtualPath, target.VirtualPath, target.QueryString);
                context.Items["RawUrl"] = context.Request.RawUrl;
                IHttpHandler appHandler = PageParser.GetCompiledPageInstance(target.VirtualPath, filename, context);

                context.RewritePath(context.Items["RawUrl"].ToString());
                return appHandler;
            }

            throw new HttpException(404, "File not found");
        }

        public void ReleaseHandler(IHttpHandler handler)
        {
        }

    }
}
